import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';

class TwinklingStars extends StatefulWidget {
  final List<Widget> starWidgets;
  final int numberOfStars;
  final Duration animationDuration;
  final Duration delayBetweenAnimations;
  final double innerRadiusRatio;  // 内圆半径与组件宽度的比例

  const TwinklingStars({
    Key? key,
    required this.starWidgets,
    this.numberOfStars = 4,
    this.animationDuration = const Duration(seconds: 2),
    this.delayBetweenAnimations = const Duration(milliseconds: 500),
    this.innerRadiusRatio = 0.3,  // 默认内圆半径为组件宽度的30%
  }) : assert(innerRadiusRatio >= 0 && innerRadiusRatio < 0.5, 'innerRadiusRatio must be between 0 and 0.5'),
        super(key: key);

  @override
  _TwinklingStarsState createState() => _TwinklingStarsState();
}

class _TwinklingStarsState extends State<TwinklingStars> with TickerProviderStateMixin {
  late List<_StarInfo> _stars;
  final Random _random = Random();
  bool _disposed = false;

  @override
  void initState() {
    super.initState();
    _initializeStars();
    _startTwinkling();
  }

  void _initializeStars() {
    _stars = List.generate(widget.numberOfStars, (_) => _createStar());
  }

  _StarInfo _createStar() {
    final controller = AnimationController(
      duration: widget.animationDuration,
      vsync: this,
    );

    final fadeAnimation = Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(parent: controller, curve: Curves.easeInOut),
    );

    final scaleAnimation = Tween<double>(begin: 0.5, end: 1).animate(
      CurvedAnimation(parent: controller, curve: Curves.easeInOut),
    );

    return _StarInfo(
      widget: widget.starWidgets[_random.nextInt(widget.starWidgets.length)],
      position: _getRandomPosition(),
      fadeAnimation: fadeAnimation,
      scaleAnimation: scaleAnimation,
      controller: controller,
    );
  }

  Offset _getRandomPosition() {
    // 生成随机角度
    double angle = _random.nextDouble() * 2 * pi;

    // 生成在内圆和外圆之间的随机半径
    double minRadius = widget.innerRadiusRatio;
    double maxRadius = 0.5;  // 外圆半径为组件宽度的一半
    double radius = minRadius + _random.nextDouble() * (maxRadius - minRadius);

    // 转换为笛卡尔坐标
    double x = 0.5 + radius * cos(angle);
    double y = 0.5 + radius * sin(angle);

    return Offset(x, y);
  }

  void _startTwinkling() {
    for (int i = 0; i < _stars.length; i++) {
      Future.delayed(widget.delayBetweenAnimations * i, () => _twinkleStar(i));
    }
  }

  void _twinkleStar(int index) {
    if (_disposed) return;

    final star = _stars[index];
    star.controller.forward().then((_) {
      if (_disposed) return;
      Future.delayed(widget.animationDuration, () {
        if (_disposed) return;
        star.controller.reverse().then((_) {
          if (_disposed) return;
          _safeSetState(() {
            _stars[index] = _createStar();
          });
          _twinkleStar(index);
        });
      });
    });
  }

  void _safeSetState(VoidCallback fn) {
    if (mounted && !_disposed) {
      setState(fn);
    }
  }

  @override
  void dispose() {
    _disposed = true;
    for (var star in _stars) {
      star.controller.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final size = constraints.maxWidth < constraints.maxHeight
            ? constraints.maxWidth
            : constraints.maxHeight;
        return SizedBox(
          width: size,
          height: size,
          child: Stack(
            children: _stars.map((star) {
              return Positioned(
                left: star.position.dx * size,
                top: star.position.dy * size,
                child: AnimatedBuilder(
                  animation: star.controller,
                  builder: (context, child) {
                    return Opacity(
                      opacity: star.fadeAnimation.value,
                      child: Transform.scale(
                        scale: star.scaleAnimation.value,
                        child: star.widget,
                      ),
                    );
                  },
                ),
              );
            }).toList(),
          ),
        );
      },
    );
  }
}

class _StarInfo {
  final Widget widget;
  final Offset position;
  final Animation<double> fadeAnimation;
  final Animation<double> scaleAnimation;
  final AnimationController controller;

  _StarInfo({
    required this.widget,
    required this.position,
    required this.fadeAnimation,
    required this.scaleAnimation,
    required this.controller,
  });
}